/**
 ******************************************************************************
 * @file	watch_ls.c
 * @brief	在串口终端上提供的光源界面

- 2017-6-23,MenglongWu,MenglongWoo@aliyun.com
 *
 Copyright (C) 2017 桂林聚联科技有限公司, Inc. All Rights Reserved.
*/





#include <stdio.h>
#include <string.h>
#include <prj_type.h>
#include <TR700Driver.h>
#include <project.h>
#include "printl.h"
#include <math.h>
#include <unos_input.h>
#include <cui.h>

#define CONFIG_USE_U_MATH (1)

struct _watch_ls_private {
	float          *dbm;
	unsigned int   *mode;
	unsigned int   *ch;
	unsigned short *s_adc;
	unsigned short *s_dac;
	unsigned short *c_adc;
	unsigned short *c_dac;
};

/*

debug:off |


```
[-9.96dBm]  ADCs: 361  DACs:450  ADCc: 359  DACc: 610
```

按下
*/
#define COUNT_CONTROL (3)
static void _draw(unsigned int select, void *v)
{
	struct _watch_ls_private *p  = (struct _watch_ls_private *)v;
	char *c_item[COUNT_CONTROL]  = {C_NORMAL, C_NORMAL, C_NORMAL};
	char *strmode[]              = {"cw", "270", "1k", "2k"};
	char *strch[]                = {"-", "1", "2", "3"};
	char *pmode;
	char *pch;

	// 高亮选中列
	c_item[select % ARRAY_SIZE(c_item)] = (C_CYAN AC_REVERSE);

	// TODO sizeof(*strmode)永远是4，正确写法是 sizeof(strmode)
	pmode = strmode[*(p->mode) % sizeof(*strmode)];
	pch   = strch  [*(p->ch)   % sizeof(*strch)];


	printf("  %s%6.2fdBm  "
	       "%s%3s  "
	       "%sCh%s   "
	       C_NORMAL "ADCs:%4d  "
	       "DACs:%4d  "
	       "ADCc:%4d  "
	       "DACc:%4d\r",

	       c_item[0], *(p->dbm),
	       c_item[1], pmode,
	       c_item[2], pch,
	       *(p->s_adc),
	       *(p->s_dac),
	       *(p->c_adc),
	       *(p->c_dac));
}

static void _key_process(unsigned int *select, void *v, int key)
{
	struct _watch_ls_private *p = (struct _watch_ls_private *)v;
	static int times = 0;

	int   deta       = 1;
	float deta_dbm   = 0.01;
	int tmp;


	if (is_fastkeydown(key)) {
		if (times++ >= 8) {
			deta = 10;
			deta_dbm = 0.10;
		}
	} else {
		times = 0;
		deta = 1;
		deta_dbm = 0.01;
	}

	switch (key) {
	case VK_DOWN:
	case 's':
		deta_dbm  = -deta_dbm;
		deta      = -deta;
	case VK_UP:
	case 'w':
		switch( (unsigned int)(*select) % COUNT_CONTROL ) {
		case 0:  // dbm
			*(p->dbm)   += deta_dbm;
			if (*(p->dbm) > COUNT_CONTROL) {
				*(p->dbm) = -20;
			} else if (*(p->dbm) < -20) {
				*(p->dbm) = 3;
			}
			break;
		case 1:  // mode
			*(p->mode) += deta;
			*(p->mode) %= LASER_MODE_COUNT;
			break;
		case 2:  // ch
			*(p->ch) += deta;
			*(p->ch) %= CTRL_CH_COUNT;
			break;
		default:
			break;
		}
		break;
	case VK_RIGHT:
	case 'd':
		(*select)++;
		break;
	case VK_LEFT:
	case 'a':
		(*select)--;
		break;
	default:
		break;
	}
}
extern float _pow(int base, float dbm);
#define TASK_DETA_READKEY (20 * _1MS)
#define TASK_DETA_UPDATE  (100 * _1MS)
void watch_ls()
{
	// 多少都无所谓，只不过如果设置为0
	unsigned int  select = 1000 * COUNT_CONTROL;
	int           key = 0;
	unsigned long task_readkey;
	unsigned long task_update_dac;

	float                   dbm   = -10;
	unsigned int            mode  = LASER_MODE_CW;
	unsigned int            ch    = CTRL_CH1;
	unsigned short          unuse = 0;
	unsigned short          adc   = 0;
	struct _watch_ls_private draw;



	draw.dbm   = &dbm;
	draw.mode  = &mode;
	draw.ch    = &ch;
	draw.s_dac = &unuse;
	draw.s_adc = &dev_ls.adc;
	draw.s_dac = &unuse;
	draw.c_adc = &adc;
	draw.c_dac = &dev_ls.dac;



	printf(C_CYAN
	       "[q]:Quit  ['w'/up , 's'/down]:Edit  "
	       "['a'/left , 's'/right']:move cursor \r\n"
	       C_NORMAL);
	task_readkey    = jiffies + TASK_DETA_READKEY;
	task_update_dac = jiffies + TASK_DETA_UPDATE;
	while(key != 'q') {
		// key = 0;
		if (time_after(jiffies, task_readkey)) {
			task_readkey = jiffies + TASK_DETA_READKEY;
			key = getkeycode();
			if (key > 0) {
				_key_process(&select, &draw, key);
				adc = GetAD(AD_CH_LS);
				Laser_dBm2Ctrl(dbm, &dev_ls);

				dev_ls.mode = mode;
				dev_ls.ch   = ch;
				Ctrl_LaserMode(&dev_ls);
				Ctrl_LaserChannel(&dev_ls);
				Ctrl_LaserDAC(&dev_ls);
				_draw(select, &draw);
			}
		}
		if (time_after(jiffies, task_update_dac)) {
			task_update_dac = jiffies + TASK_DETA_UPDATE;
			adc = GetAD(AD_CH_LS);
			AutoCtrl_LS();
			_draw(select, &draw);
		}
	}
	printf("\r\n");
}


